import autoDisposeWhenUnload from "./autoDisposeWhenUnload";

const instanceList = [];
const dataList = [];
let staticInstanceIndex = -1;

autoDisposeWhenUnload(function () {
    instanceList.forEach(i => i?.destroy());
    instanceList.splice(0, instanceList.length);
    dataList.splice(0, dataList.length);
});

export default class SimpleEvent {
    constructor() {
        instanceList.push(this);
        dataList.push({});
    }

    addEventListener(eventName, callback) {
        const events = dataList[instanceList.indexOf(this)];
        if (!events.hasOwnProperty(eventName)) {
            events[eventName] = [];
        }

        const exists = events[eventName];
        if (-1 === exists.indexOf(callback)) {
            exists.push(callback);
        }
    }

    removeEventListener(eventName, callback) {
        const events = dataList[instanceList.indexOf(this)];
        if (events.hasOwnProperty(eventName)) {
            const callbacks = events[eventName];
            if (-1 < callbacks.indexOf(callback)) {
                callbacks.splice(callbacks.indexOf(callback), 1);
            }

            if (0 === callbacks.length) {
                delete events[eventName];
            }
        }
    }

    trigger(eventName, ...args) {
        const events = dataList[instanceList.indexOf(this)];
        if (events.hasOwnProperty(eventName)) {
            events[eventName].slice().forEach(function (cb) {
                cb(...args);
            });
        }
    }

    destroy() {
        const index = instanceList.indexOf(this);
        instanceList[index] = null;
        dataList[index] = null;
    }

    static addEventListener(eventName, callback) {
        if (-1 === staticInstanceIndex) {
            const instance = new SimpleEvent();
            staticInstanceIndex = instanceList.indexOf(instance);
        }
        instanceList[staticInstanceIndex].addEventListener(eventName, callback);
    }

    static removeEventListener(eventName, callback) {
        if (-1 === staticInstanceIndex) {
            const instance = new SimpleEvent();
            staticInstanceIndex = instanceList.indexOf(instance);
        }
        instanceList[staticInstanceIndex].removeEventListener(eventName, callback);
    }

    static trigger(eventName, ...args) {
        if (-1 === staticInstanceIndex) {
            const instance = new SimpleEvent();
            staticInstanceIndex = instanceList.indexOf(instance);
        }
        instanceList[staticInstanceIndex].trigger(eventName, ...args);
    }
}
